package xuecheng.tool.api.dto;

import java.io.Serializable;
import java.util.Date;

import org.springframework.http.HttpStatus;

import cn.hutool.core.util.IdUtil;
import lombok.Getter;
import lombok.ToString;

/**
 * api 响应结果实体
 *
 * @author PengXueCheng
 * @version 1.0.0
 **/
@Getter
@ToString
public class ApiResultDTO<T> implements Serializable {

    /**
     * 请求响应ID
     */
    private String id;

    /**
     * 资源创建时间
     */
    private Date createTime;

    /**
     * 资源修改时间
     */
    private Date updateTime;

    /**
     * 响应状态码{@link HttpStatus}
     */
    private Integer status;

    /**
     * 错误信息
     */
    private String error;

    /**
     * 响应数据
     */
    private T data;

    public ApiResultDTO(HttpStatus status, T data) {
        this(status, data, null);
    }

    public ApiResultDTO(HttpStatus status, T data, String error) {
        this(status, error, data);
    }

    private ApiResultDTO(HttpStatus status, String error, T data) {
        this.id = IdUtil.fastUUID();
        this.status = status.value();
        this.createTime = new Date(System.currentTimeMillis());
        this.updateTime = new Date(System.currentTimeMillis());
        this.error = error;
        this.data = data;
    }

    /**
     * 200 成功
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ApiResultDTO<T> ok(T data) {
        return new ApiResultDTO<>(HttpStatus.OK, data);
    }

    /**
     * 204 无内容
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ApiResultDTO<T> noContent(T data) {
        return new ApiResultDTO<>(HttpStatus.NO_CONTENT, data);
    }

    /**
     * 400 错误的请求
     *
     * @param data
     * @param error
     * @param <T>
     * @return
     */
    public static <T> ApiResultDTO<T> badRequest(T data, String error) {
        return new ApiResultDTO<>(HttpStatus.BAD_REQUEST, data, error);
    }

    /**
     * 401 未经授权
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ApiResultDTO<T> unauthorized(T data) {
        return new ApiResultDTO<>(HttpStatus.UNAUTHORIZED, data);
    }

    /**
     * 403 禁止
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ApiResultDTO<T> forbidden(T data) {
        return new ApiResultDTO<>(HttpStatus.FORBIDDEN, data);
    }

    /**
     * 500 内部服务器错误
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ApiResultDTO<T> internalServerError(T data) {
        return new ApiResultDTO<>(HttpStatus.INTERNAL_SERVER_ERROR, data);
    }

}
